// ---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "CacheThread.h"
#include "main.h"
#include <vector>
#include "functions.h"
#pragma package(smart_init)
#include <algorithm>
using namespace std;

extern ULONG totcachsize;
extern vector<CACHE>cache;
extern TCriticalSection *ccs;
extern TEvent *cev;

__fastcall CacheThread::CacheThread(bool CreateSuspended):TThread(CreateSuspended)
{
}

bool sortcachebyopid(CACHE c1, CACHE c2)
{
    return c1.opid > c2.opid;
}

// ---------------------------------------------------------------------------
void __fastcall CacheThread::Execute()
{
    NameThreadForDebugging("CacheThread");

    while (1)
    {
        cev->ResetEvent();
        Sleep(1);



        if (cev->WaitFor(0) == wrSignaled)
            continue;

        cev->ResetEvent();

        ccs->Enter();

        sort(cache.begin(), cache.end(), sortcachebyopid);

        for (vector<CACHE>::iterator it = cache.begin();it!=cache.end();it++)
        {
            if ((*it).unsaved && ((GetTickCount() - (*it).changed) > 1000))
            {
                deb("cache: saving %5lu @ %8lu, opid: %d", (*it).len, (*it).offset, (*it).opid);
                LARGE_INTEGER li;
                li.QuadPart = (*it).offset;
                paintdisk(5, li, (*it).len, 0);
                double ms;
                ms = GetTickCount();
                nwrite((ULONG)(*it).buf, (*it).offset, (*it).len, 0, true);
                li.QuadPart = 0;
                paintdisk(4, li, 1, 0);
                // HeapFree(GetProcessHeap(), 0, (*it).buf);

                ms = (GetTickCount() - ms) /1000.0;
                deb("       saved in %.2f s", ms);
                // totcachsize-=(*it).len;
                // it = cache.erase(it);
                (*it).unsaved = false;
                (*it).changed = GetTickCount();
                // if(it == cache.end())
                if (cev->WaitFor(0) == wrSignaled)
                {
                    deb("cache flush breaked due to signal");
                    break;
                }
            }
        }
        ccs->Leave();
    }
}
// ---------------------------------------------------------------------------
